
/*
 * 表时间切片逻辑
 * 文件名：DateTableShardingAlgorithm.java
 * 修改人：chenliang
 * 修改时间：2018年8月20日
 * 修改内容：
 */
package com.kalvan.core.sharding.algorithm;

import com.google.common.collect.Range;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 根据时间月份分表
 */
public class DateMMTablePreciseAlgorithm
        implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Comparable<Date>> {

    public DateMMTablePreciseAlgorithm() {
        super();
    }

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {

        SimpleDateFormat sdf = new SimpleDateFormat("MM");
        for (String each : availableTargetNames) {
            if (each.endsWith("_" + sdf.format(shardingValue.getValue()))) {
                return each;
            }
        }
        throw new UnsupportedOperationException();
    }

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                         RangeShardingValue<Comparable<Date>> shardingValue) {
        List<String> result = new ArrayList<String>();
        DateFormat sdf = new SimpleDateFormat("MM");
        Range<Comparable<Date>> ranges = shardingValue.getValueRange();
        try {
            String startDay = ranges.lowerEndpoint().toString().substring(0, 7);
            String endDay = ranges.upperEndpoint().toString().substring(0, 7);
            Date startTime = DateUtils.parseDate(startDay, "yyyy-MM");
            Date endTime = DateUtils.parseDate(endDay, "yyyy-MM");
            String tablePrefix = "";
            for (String each : availableTargetNames) {
                tablePrefix = each.substring(0, each.lastIndexOf("_"));
                break;
            }
            Calendar cal = Calendar.getInstance();
            while (startTime.getTime() <= endTime.getTime()) {
                result.add(tablePrefix + "_" + sdf.format(startTime));
                cal.setTime(startTime);// 设置起时间
                cal.add(Calendar.MONTH, 1);
                startTime = cal.getTime();
            }
            // 反转排序，由于sharing-jdbc 跨分表查询大结果集时时间反序会按第一个分表的反序开始显示数据，所以要把较后的分表先去执行
            Collections.reverse(result);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }
}
